#pragma once
#include <time.h>
#include <stdlib.h>
#include <list>
#include "DO.h"

using namespace std;

class ApplicationSpecific : public DO
{
	public:
	ApplicationSpecific();
	// arg is the argument mentioning the application no, mentioned in bracket
	ApplicationSpecific(int arg, WORD length_arg, const BYTE* buffer); //primitive application specific DO
	ApplicationSpecific(int arg, const list<DO>& collection); //constructed application specific DO
};

class Sequence : public DO
{
	public:
	Sequence();
	Sequence(WORD length_arg, const BYTE* buffer); //primitive DO
	Sequence(const list<DO>& collection); //constructed DO
	Sequence(DO* d);
};

class ObjectIdentifier : public DO
{
	public:
	ObjectIdentifier();
	ObjectIdentifier(unsigned long* buffer, int len);
};

class ContextSpecific : public DO
{
	public:
	ContextSpecific();
	// arg is the number mentioned within brackets
	ContextSpecific(int arg, WORD length_arg, const BYTE* buffer);//primitive DO
	ContextSpecific(int arg, const list<DO>& collection);//constructed DO
};

class ASNInteger : public DO
{
	public:
	ASNInteger();
	ASNInteger(const BYTE* buffer, int len);

};

class Null : public DO
{
	public:
	Null();
};

class BitString : public DO
{
	public:
	BitString();
	BitString(int length_arg, const BYTE* buffer);//primitve DO
	BitString(const list<DO>& collection);//constructed DO
	BitString(DO *d);
};

class OctetString : public DO
{
	public:
	OctetString();
        OctetString(int length_arg, const BYTE* buffer);//primitive DO
        OctetString(const list<DO>& collection);//constructed DO
	OctetString(DO *d);
};

class TimeStamp : public DO
{
        public:
        TimeStamp();
        TimeStamp(int i, struct tm *t);
	TimeStamp(int i, const BYTE* buffer);//primitive DO
	
};

class ASNBoolean : public DO
{
	public:
	ASNBoolean();
	ASNBoolean(bool b, BYTE* val);
};

class Set : public DO
{
	public:
	Set();
	Set(WORD length_arg, const BYTE* buffer);
	Set(const list<DO>& collection);	
	Set(DO* d);
};

class Choice : public DO
{
	public:
	Choice();
	Choice(const list<DO>& collection);
	Choice(DO* d);
};

class RelativeOid : public DO
{
	public:
	RelativeOid();
	RelativeOid(unsigned long *buffer, int len);
};

class CharacterString : public DO
{
	public:
	CharacterString();
	CharacterString(const list<DO>& collection);
};

class EmbeddedPDV : public DO
{
	public:
	EmbeddedPDV();
	EmbeddedPDV(const list<DO>& collection);
};

class InstanceOf : public DO
{
	public:
	InstanceOf();
	InstanceOf(const list<DO>& collection);
};

class External : public DO
{
	public:
	External();
	External(const list<DO>& collection);
};

class Tagged : public DO
{
	public:
	Tagged();
	Tagged(int i, WORD tag, DO *d);
};

class ASNReal : public DO
{
	public:
	ASNReal();
	ASNReal(int NR, const char* buffer);
	ASNReal(int sign, int mantissa_len, BYTE *mantissa, int base, int exp_len, BYTE *exponent, int scale );
};

class CharacterStrings : public DO
{
	public:
	CharacterStrings(int type, int len, const BYTE *buffer);
};
